<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>类</title>
    <script src="js/traceur.js"></script>
    <script src="js/bootstrap.js"></script>
    <script type="module">

        //使用类声明来定义一个类
        class Student {
            constructor(name) {
                this.name = name;
            }
        }
        var s1 = new Student("Eden");
        console.log(s1.name); // "Eden"
        //上面代码相当于如下代码
        function Student1(name) {
            this.name = name;
        }
        var s1 = new Student1("Eden");
        console.log(s1.name); //Output "Eden"

        //类其实是一个函数
        class Student2 {
            constructor(name) {
                this.name = name;
            }
        }
        function School(name) {
            this.name = name;
        }
        console.log(typeof Student2); //function
        console.log(typeof School == typeof Student); //true

        //使用类的表达式来命令一个类
        var Student3 = class {
            constructor(name) {
                this.name = name;
            }
        }
        var s1 = new Student3("Eden");
        console.log(s1.name); // "Eden"
        //使用以前的方法
        var Student4 = function (name) {
            this.name = name;
        }
        var s1 = new Student4("Eden");
        console.log(s1.name); // "Eden"

        //扩展方法
        class Person {
            constructor(name, age) {
                this.name = name;
                this.age = age;
            }

            printProfile() {
                console.log("Name is: " + this.name + " and Age is: " +
                    this.age);
            }
        }
        var p = new Person("Eden", 12)
        p.printProfile();  //Name is: Eden and Age is: 12
        console.log("printProfile" in p.__proto__); // true
        console.log("printProfile" in Person.prototype); // true
        //上面的代码相当于之前的
        function Person1(name, age) {
            this.name = name;
            this.age = age;
        }
        Person1.prototype.printProfile = function () {
            console.log("Name is: " + this.name + " and Age is: " +
                this.age);
        }
        var p = new Person1("Eden", 12)
        p.printProfile(); //Name is: Eden and Age is: 12
        console.log("printProfile" in p.__proto__);// true
        console.log("printProfile" in Person.prototype); // true

        //方法可以添加类的行为中，以定义访问器属性的get和set属性
        class Person2 {
            constructor(name) {
                this._name_ = name;
            }

            get name() {
                return this._name_;
            }

            set name(name) {
                this._name_ = name;
            }
        }
        var p = new Person2("Eden");
        console.log(p.name); //Eden
        p.name = "John";
        console.log(p.name); //John
        console.log("name" in p.__proto__); //true
        console.log("name" in Person.prototype); //true
        console.log(Object.getOwnPropertyDescriptor(p.__proto__, "name").set); //function name(name) { this._name_ = name; }
        console.log(Object.getOwnPropertyDescriptor(Person2.prototype, "name").get); //function name() { return this._name_; }
        console.log(Object.getOwnPropertyDescriptor(p, "_name_").value); //John

        //生成器方法被添加到该类的prototype属性中
        class myClass {
            * generator_function() {
                yield 1;
                yield 2;
                yield 3;
                yield 4;
                yield 5;
            }
        }
        var obj = new myClass();
        let generator = obj.generator_function();
        console.log(generator.next().value);  //1
        console.log(generator.next().value);  //2
        console.log(generator.next().value);  //3
        console.log(generator.next().value); //4
        console.log(generator.next().value); //5
        console.log(generator.next().done); //true
        console.log("generator_function" in myClass.prototype); //true

        //定义静态方法,静态方法相当于对象本身的自己独有的方法
        class Student5 {
            constructor(name) {
                this.name = name;
            }

            static findName(student) {
                return student.name;
            }
        }
        var s = new Student5("Eden");
        var name = Student5.findName(s);
        console.log(name); //"Eden"
        //以前的方法
        function Student(name) {
            this.name = name;
        }
        Student.findName = function (student) {
            return student.name;
        }
        var s = new Student("Eden");
        var name = Student.findName(s);
        console.log(name); // "Eden"
    </script>
</head>
<body>

</body>
</html>